package com.generalbackend.common.util;

import cn.hutool.core.lang.Pair;
import org.apache.commons.collections4.CollectionUtils;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * shell工具类
 *
 * @author tim.xie
 * @date 2022/6/24 10:38
 */
public class ShellUtils {

    /**
     * 执行 shell 命令
     *
     * @param shellStr shell 命令
     * @return 返回 shell 命令 结果
     */
    public static Pair<List<String>, List<String>> execute(String shellStr) {
        Process process;
        try {
            process = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", shellStr});
        } catch (IOException ioException) {
            return null;
        }
        List<String> inputResult = getResult(process, process.getInputStream());
        List<String> errorResult = getResult(process, process.getErrorStream());

        return new Pair<>(inputResult, errorResult);
    }

    /**
     * 获取 执行结果的字符串
     *
     * @param shellStr 命令行
     * @return 返回 结果字符串
     */
    public static String getResultStr(String shellStr) {
        return getInputResultStr(shellStr) + getErrorResultStr(shellStr);
    }

    /**
     * 获取 InputStream 的值
     *
     * @param shellStr 命令行
     * @return 返回 InputStream 的值
     */
    public static List<String> getInputResult(String shellStr) {
        return execute(shellStr).getKey();
    }

    /**
     * 获取 InputStream 的值
     *
     * @param shellStr 命令行
     * @return 返回 InputStream 的值
     */
    public static List<String> getErrorResult(String shellStr) {
        return execute(shellStr).getValue();
    }

    /**
     * 获取 InputStream 的值
     *
     * @param shellStr 命令行
     * @return 返回 InputStream 的值
     */
    public static String getInputResultStr(String shellStr) {
        return getListString(execute(shellStr).getKey(), System.lineSeparator());
    }

    /**
     * 获取 InputStream 的值
     *
     * @param shellStr 命令行
     * @return 返回 InputStream 的值
     */
    public static String getErrorResultStr(String shellStr) {
        return getListString(execute(shellStr).getValue(), System.lineSeparator());
    }

    /**
     * list 转 字符串
     *
     * @param list      集合
     * @param splitChar 分隔符
     * @return 返回 字符串
     */
    private static String getListString(List<String> list, String splitChar) {
        if (CollectionUtils.isEmpty(list)) {
            return "";
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (String value : list) {
            stringBuilder.append(value);
            stringBuilder.append(splitChar);
        }
        return stringBuilder.toString();
    }

    /**
     * 获取结果
     *
     * @param process     进程信息
     * @param inputStream 输入流
     * @return 返回 结果
     */
    private static List<String> getResult(Process process, InputStream inputStream) {
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
        LineNumberReader input = new LineNumberReader(inputStreamReader);
        String line;
        try {
            process.waitFor();
        } catch (InterruptedException e) {
            return Collections.emptyList();
        }
        List<String> processList = new ArrayList<>();
        try {
            while ((line = input.readLine()) != null) {
                processList.add(line);
            }
        } catch (IOException ioException) {
            return Collections.emptyList();
        }
        return processList;
    }
}
